import { appApi } from "@/api";
import { Action, App, Seed } from "@/seed-application/types";
import { getActions, getDataActions, getFieldActions, permissionsToTree } from "@/seed-application/utils/AppUtil";
import { createApp } from "vue";
import { ComponentManager } from "./manager/ComponentManager";
import { RouteManager } from "./manager/RouteManager";
import { LibManager } from "./manager/LibManager";
import { MenuManager } from "./manager/MenuManager";
import { createPinia } from "pinia";
import ElementPlus from 'element-plus'
import zhCn from 'element-plus/es/locale/lang/zh-cn'
import { router } from "@/router";
import { Initializer } from "./utils/Initializer";
import Container from "./Container";
import { ElementManager } from "./manager/ElementManager";

export type SeedContext = {
  actions: Record<string, Action>
  seeds: Record<string, Seed>
}

export const libManager = new LibManager()
export const componentManager = new ComponentManager()
export const elementManager = new ElementManager()
export const routeManager = new RouteManager()
export const menuManager = new MenuManager()

export class SeedApplication {
  private app: App
  private seedContext: SeedContext
  private seedContexts: Record<string, SeedContext>

  public async init() {
    libManager.init()

    const res = await appApi()
    this.app = res.data

    new Initializer(this.app, this.seedContext, this.seedContexts).init()
    routeManager.init(this.app)
    menuManager.init(this.app)

    const pinia = createPinia()
    const vueApp = this.getVueApp()
    vueApp.use(pinia)
    vueApp.use(router)
    vueApp.use(ElementPlus, { locale: zhCn })
    vueApp.mount('#app')

    console.info('app', this.app)
  }

  public getVueApp() {
    const props = this.app.rootProps
    const layout = this.app.rootLayout
    const [root, rootProps] = layout
      ? [Container, { layout, props }]
      : [componentManager.getComponent('root', this.app.root), props]
    return createApp(root, rootProps)
  }

  public getApp() {
    return this.app
  }

  public getActions() {
    return getActions(this.app)
  }

  public getDataActions() {
    return getDataActions(this.app)
  }

  public getFieldActions() {
    return getFieldActions(this.app)
  }

  public permissionsToTree(permissions: string[]) {
    return permissionsToTree(this.app, permissions)
  }

  public getHome(homeName: string, microName?: string) {
    if(microName) {
      const micro = this.app.micros?.[microName]
      return micro?.homes?.[homeName]
    }

    return this.app.homes?.[homeName]
  }

  public getAction(actionName: string, seedName?: string, microName?: string) {
    if(microName) {
      const micro = this.app.micros?.[microName]
      return seedName ? micro?.seeds?.[seedName]?.actions?.[actionName] : micro?.actions?.[actionName]
    }

    return seedName ? this.app.seeds?.[seedName]?.actions?.[actionName] : this.app.actions?.[actionName]
  }

  public getSeed(seedName: string, microName?: string) {
    if(microName) {
      const micro = this.app.micros?.[microName]
      return micro?.seeds?.[seedName]
    }

    return this.app.seeds?.[seedName]
  }

  public setSeedContext(seedContext: SeedContext) {
    this.seedContext = seedContext
  }

  public getSeedContext(key?: string) {
    return key ? this.seedContexts?.[key] : this.seedContext
  }

  public putSeedContext(key: string, seedContext: SeedContext) {
    this.seedContexts[key] = seedContext
  }
}